package com.wyz.saas.common.utils

import android.content.Context
import android.util.SparseArray
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager

class NavHelper<T> {
    /**
     * 我们的所有的Tab基础属性
     * */
    class Tab<T> {
        var clx: Class<*> // Fragment对应的Class信息
        var extra: T// 额外的字段，用户自己设定需要使用
        var fragment: Fragment? = null// 内部缓存的对应的Fragment
        constructor(clx: Class<*>, extra: T) {
            this.clx = clx
            this.extra = extra
        }
    }

    /**
     * 定义事件处理完成后的回调接口
     */
    interface OnTabChangedListener<T> {
        fun onTabChanged(
            newTab: Tab<T>?,
            oldTab: Tab<T>?
        )
    }

    // 所有的Tab集合
    private val tabs = SparseArray<Tab<T>?>()

    // 用于初始化的必须参数
    private val context: Context
    private val containerId: Int
    private val fragmentManager: FragmentManager
    private var listener: OnTabChangedListener<T>?= null

    // 当前的一个选中的Tab
    private var currentTab: Tab<T>? = null

    constructor(
        context: Context,
        containerId: Int,
        fragmentManager: FragmentManager,
        listener: OnTabChangedListener<T>
    ) {
        this.context = context
        this.containerId = containerId
        this.fragmentManager = fragmentManager
        this.listener = listener
    }

    /**
     * 添加Tab
     */
    fun add(
        menuId: Int,
        tab: Tab<T>
    ): NavHelper<T> {
        tabs.put(menuId, tab)
        return this
    }

    /**
     * 获取当前的显示的Tab
     */
    fun getCurrentTab(): Tab<T>? {
        return currentTab
    }

    /**
     * 执行点击菜单的操作
     */
    fun performClickMenu(menuId: Int): Boolean {
        // 集合中寻找点击的菜单对应的Tab，
        // 如果有则进行处理
        tabs[menuId]?.let {
            doSelect(it)
            return true
        } ?: let {
            return false
        }

    }

    /**
     * 进行真实的Tab选择操作
     */
    private fun doSelect(tab: Tab<T>?) {
        var oldTab: Tab<T>? = null
        currentTab?.let {
            oldTab = it
            if (oldTab == tab) {
                // 如果说当前的Tab就是点击的Tab，
                // 那么我们不做处理
                notifyTabReselect(tab)
                return
            }
        }
        // 赋值并调用切换方法
        currentTab = tab
        doTabChanged(currentTab, oldTab)
    }

    /**
     * 进行Fragment的真实的调度操作
     */
    private fun doTabChanged(
        newTab: Tab<T>?,
        oldTab: Tab<T>?
    ) {
        val ft = fragmentManager.beginTransaction()
        oldTab?.let {
            it.fragment?.let { it_1 ->
                // 从界面移除，但是还在Fragment的缓存空间中
                ft.detach(it_1)
            }
        }
        newTab?.let {
            newTab.fragment?.let {
                // 从FragmentManger的缓存空间中重新加载到界面中
                ft.attach(it)
            } ?: let {
                // 首次新建
                val fragment: Fragment = Fragment.instantiate(context, newTab.clx.name, null)
                // 缓存起来
                newTab.fragment = fragment
                // 提交到FragmentManger
                ft.add(containerId, fragment, newTab.clx.name)
            }
        }
        // 提交事务
        ft.commit()
        // 通知回调
        notifyTabSelect(newTab, oldTab)
    }

    /**
     * 回调我们的监听器
     */
    private fun notifyTabSelect(
        newTab: Tab<T>?,
        oldTab: Tab<T>?
    ) {
        listener?.onTabChanged(newTab, oldTab)
    }

    private fun notifyTabReselect(tab: Tab<T>?) {
        // TODO 二次点击Tab所做的操作
    }
}